<!DOCTYPE html>
<html style="display: none;" lang="zh">
    <head>
    <meta charset="utf-8">
    <!--
        © Material Theme
        https://github.com/viosey/hexo-theme-material
        Version: 1.5.2 -->
    <script>
        window.materialVersion = "1.5.2"
        // Delete localstorage with these tags
        window.oldVersion = [
            'codestartv1',
            '1.3.4',
            '1.4.0',
            '1.4.0b1',
            '1.5.0'
        ]
    </script>

    <!-- dns prefetch -->
    <meta http-equiv="x-dns-prefetch-control" content="on">


    <link rel="dns-prefetch" href="https://cdn1.lncld.net"/>













    <!-- Meta & Info -->
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

    <!-- Title -->
    
    <title>
        
            JVM学习01-JVM内存模型 | 
        
        android开发者
    </title>

    <!-- Favicons -->
    <link rel="icon shortcut" type="image/ico" href="/img/favicon.png">
    <link rel="icon" href="/img/favicon.png">

    <meta name="format-detection" content="telephone=no"/>
    <meta name="description" itemprop="description" content="android开发工程师，学习，记录。">
    <meta name="keywords" content="android,java">
    <meta name="theme-color" content="#0097A7">

    <!-- Disable Fucking Bloody Baidu Tranformation -->
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />

    <!--[if lte IE 9]>
        <link rel="stylesheet" href="/css/ie-blocker.css">

        
            <script src="/js/ie-blocker.zhCN.js"></script>
        
    <![endif]-->

    <!-- Import lsloader -->
    <script>(function(){window.lsloader={jsRunSequence:[],jsnamemap:{},cssnamemap:{}};lsloader.removeLS=function(a){try{localStorage.removeItem(a)}catch(b){}};lsloader.setLS=function(a,c){try{localStorage.setItem(a,c)}catch(b){}};lsloader.getLS=function(a){var c="";try{c=localStorage.getItem(a)}catch(b){c=""}return c};versionString="/*"+(window.materialVersion||"unknownVersion")+"*/";lsloader.clean=function(){try{var b=[];for(var a=0;a<localStorage.length;a++){b.push(localStorage.key(a))}b.forEach(function(e){var f=lsloader.getLS(e);if(window.oldVersion){var d=window.oldVersion.reduce(function(g,h){return g||f.indexOf("/*"+h+"*/")!==-1},false);if(d){lsloader.removeLS(e)}}})}catch(c){}};lsloader.clean();lsloader.load=function(f,a,b,d){if(typeof b==="boolean"){d=b;b=undefined}d=d||false;b=b||function(){};var e;e=this.getLS(f);if(e&&e.indexOf(versionString)===-1){this.removeLS(f);this.requestResource(f,a,b,d);return}if(e){var c=e.split(versionString)[0];if(c!=a){console.log("reload:"+a);this.removeLS(f);this.requestResource(f,a,b,d);return}e=e.split(versionString)[1];if(d){this.jsRunSequence.push({name:f,code:e});this.runjs(a,f,e)}else{document.getElementById(f).appendChild(document.createTextNode(e));b()}}else{this.requestResource(f,a,b,d)}};lsloader.requestResource=function(b,e,a,c){var d=this;if(c){this.iojs(e,b,function(h,f,g){d.setLS(f,h+versionString+g);d.runjs(h,f,g)})}else{this.iocss(e,b,function(f){document.getElementById(b).appendChild(document.createTextNode(f));d.setLS(b,e+versionString+f)},a)}};lsloader.iojs=function(d,b,g){var a=this;a.jsRunSequence.push({name:b,code:""});try{var f=new XMLHttpRequest();f.open("get",d,true);f.onreadystatechange=function(){if(f.readyState==4){if((f.status>=200&&f.status<300)||f.status==304){if(f.response!=""){g(d,b,f.response);return}}a.jsfallback(d,b)}};f.send(null)}catch(c){a.jsfallback(d,b)}};lsloader.iocss=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.iofonts=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.runjs=function(f,c,e){if(!!c&&!!e){for(var b in this.jsRunSequence){if(this.jsRunSequence[b].name==c){this.jsRunSequence[b].code=e}}}if(!!this.jsRunSequence[0]&&!!this.jsRunSequence[0].code&&this.jsRunSequence[0].status!="failed"){var a=document.createElement("script");a.appendChild(document.createTextNode(this.jsRunSequence[0].code));a.type="text/javascript";document.getElementsByTagName("head")[0].appendChild(a);this.jsRunSequence.shift();if(this.jsRunSequence.length>0){this.runjs()}}else{if(!!this.jsRunSequence[0]&&this.jsRunSequence[0].status=="failed"){var d=this;var a=document.createElement("script");a.src=this.jsRunSequence[0].path;a.type="text/javascript";this.jsRunSequence[0].status="loading";a.onload=function(){d.jsRunSequence.shift();if(d.jsRunSequence.length>0){d.runjs()}};document.body.appendChild(a)}}};lsloader.tagLoad=function(b,a){this.jsRunSequence.push({name:a,code:"",path:b,status:"failed"});this.runjs()};lsloader.jsfallback=function(c,b){if(!!this.jsnamemap[b]){return}else{this.jsnamemap[b]=b}for(var a in this.jsRunSequence){if(this.jsRunSequence[a].name==b){this.jsRunSequence[a].code="";this.jsRunSequence[a].status="failed";this.jsRunSequence[a].path=c}}this.runjs()};lsloader.cssfallback=function(e,c,b){if(!!this.cssnamemap[c]){return}else{this.cssnamemap[c]=1}var d=document.createElement("link");d.type="text/css";d.href=e;d.rel="stylesheet";d.onload=d.onerror=b;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(d,a)};lsloader.runInlineScript=function(c,b){var a=document.getElementById(b).innerText;this.jsRunSequence.push({name:c,code:a});this.runjs()}})();</script>

    <!-- Import queue -->
    <script>function Queue(){this.dataStore=[];this.offer=b;this.poll=d;this.execNext=a;this.debug=false;this.startDebug=c;function b(e){if(this.debug){console.log("Offered a Queued Function.")}if(typeof e==="function"){this.dataStore.push(e)}else{console.log("You must offer a function.")}}function d(){if(this.debug){console.log("Polled a Queued Function.")}return this.dataStore.shift()}function a(){var e=this.poll();if(e!==undefined){if(this.debug){console.log("Run a Queued Function.")}e()}}function c(){this.debug=true}}var queue=new Queue();</script>

    <!-- Import CSS -->
    
        <style id="material_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_css","/css/material.min.css?Z7a72R1E4SxzBKR/WGctOA==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
        <style id="style_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("style_css","/css/style.min.css?NKhlKQkXw/c66TR5p4wO+w==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>

        

    

    

    <!-- Config CSS -->

<!-- Other Styles -->
<style>
  body, html {
    font-family: Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
    overflow-x: hidden !important;
  }
  
  code {
    font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
  }

  a {
    color: #00838F;
  }

  .mdl-card__media,
  #search-label,
  #search-form-label:after,
  #scheme-Paradox .hot_tags-count,
  #scheme-Paradox .sidebar_archives-count,
  #scheme-Paradox .sidebar-colored .sidebar-header,
  #scheme-Paradox .sidebar-colored .sidebar-badge{
    background-color: #0097A7 !important;
  }

  /* Sidebar User Drop Down Menu Text Color */
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:hover,
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:focus {
    color: #0097A7 !important;
  }

  #post_entry-right-info,
  .sidebar-colored .sidebar-nav li:hover > a,
  .sidebar-colored .sidebar-nav li:hover > a i,
  .sidebar-colored .sidebar-nav li > a:hover,
  .sidebar-colored .sidebar-nav li > a:hover i,
  .sidebar-colored .sidebar-nav li > a:focus i,
  .sidebar-colored .sidebar-nav > .open > a,
  .sidebar-colored .sidebar-nav > .open > a:hover,
  .sidebar-colored .sidebar-nav > .open > a:focus,
  #ds-reset #ds-ctx .ds-ctx-entry .ds-ctx-head a {
    color: #0097A7 !important;
  }

  .toTop {
    background: #757575 !important;
  }

  .material-layout .material-post>.material-nav,
  .material-layout .material-index>.material-nav,
  .material-nav a {
    color: #757575;
  }

  #scheme-Paradox .MD-burger-layer {
    background-color: #757575;
  }

  #scheme-Paradox #post-toc-trigger-btn {
    color: #757575;
  }

  .post-toc a:hover {
    color: #00838F;
    text-decoration: underline;
  }

</style>


<!-- Theme Background Related-->

    <style>
      body{
        background-color: #F5F5F5;
      }

      /* blog_info bottom background */
      #scheme-Paradox .material-layout .something-else .mdl-card__supporting-text{
        background-color: #fff;
      }
    </style>




<!-- Fade Effect -->

    <style>
      .fade {
        transition: all 800ms linear;
        -webkit-transform: translate3d(0,0,0);
        -moz-transform: translate3d(0,0,0);
        -ms-transform: translate3d(0,0,0);
        -o-transform: translate3d(0,0,0);
        transform: translate3d(0,0,0);
        opacity: 1;
      }

      .fade.out{
        opacity: 0;
      }
    </style>


<!-- Import Font -->
<!-- Import Roboto -->

    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">


<!-- Import Material Icons -->


    <style id="material_icons"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_icons","/css/material-icons.css?pqhB/Rd/ab0H2+kZp0RDmw==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>




    <!-- Import jQuery -->
    
        <script>lsloader.load("jq_js","/js/jquery.min.js?qcusAULNeBksqffqUM2+Ig==", true)</script>
    

    <!-- WebAPP Icons -->
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="application-name" content="android开发者">
    <meta name="msapplication-starturl" content="http://www.xincc.top/2017/03/12/java/JVM学习01-JVM内存模型/">
    <meta name="msapplication-navbutton-color" content="#0097A7">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-title" content="android开发者">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon" href="/img/favicon.png">

    <!-- Site Verification -->
    
    

    <!-- RSS -->
    

    <!-- The Open Graph protocol -->
    <meta property="og:url" content="http://www.xincc.top/2017/03/12/java/JVM学习01-JVM内存模型/">
    <meta property="og:type" content="blog">
    <meta property="og:title" content="JVM学习01-JVM内存模型 | android开发者">
    <meta property="og:image" content="/img/favicon.png">
    <meta property="og:description" content="android开发工程师，学习，记录。">
    <meta property="og:article:tag" content="java"> 

    
        <meta property="article:published_time" content="Sun Mar 12 2017 13:00:34 GMT+0800">
        <meta property="article:modified_time" content="Sun May 06 2018 16:42:00 GMT+0800">
    

    <!-- The Twitter Card protocol -->
    <meta name="twitter:card" content="summary_large_image">

    <!-- Add canonical link for SEO -->
    
        <link rel="canonical" href="http://www.xincc.top/2017/03/12/java/JVM学习01-JVM内存模型/index.html" />
    

    <!-- Structured-data for SEO -->
    
        


<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "mainEntityOfPage": "http://www.xincc.top/2017/03/12/java/JVM学习01-JVM内存模型/index.html",
    "headline": "JVM学习01-JVM内存模型",
    "datePublished": "Sun Mar 12 2017 13:00:34 GMT+0800",
    "dateModified": "Sun May 06 2018 16:42:00 GMT+0800",
    "author": {
        "@type": "Person",
        "name": "xinwii",
        "image": {
            "@type": "ImageObject",
            "url": "/img/avatar.png"
        },
        "description": "Hi, nice to meet you"
    },
    "publisher": {
        "@type": "Organization",
        "name": "android开发者",
        "logo": {
            "@type":"ImageObject",
            "url": "/img/favicon.png"
        }
    },
    "keywords": ",javaandroid",
    "description": "android开发工程师，学习，记录。",
}
</script>


    

    <!-- Analytics -->
    
    
        <script>
    var _hmt = _hmt || [];
    (function() {var hm = document.createElement('script');
    hm.src = 'https://hm.baidu.com/hm.js?ee8e425850499b806260824b0147ff70';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(hm, s);
    })();
</script>
    
    

    <!-- Custom Head -->
    

</head>


    
        <body id="scheme-Paradox" class="lazy">
            <div class="material-layout  mdl-js-layout has-drawer is-upgraded">
                

                <!-- Main Container -->
                <main class="material-layout__content" id="main">

                    <!-- Top Anchor -->
                    <div id="top"></div>

                    
                        <!-- Hamburger Button -->
                        <button class="MD-burger-icon sidebar-toggle">
                            <span class="MD-burger-layer"></span>
                        </button>
                    

                    <!-- Post TOC -->

    
    <!-- Back Button -->
    <!--
    <div class="material-back" id="backhome-div" tabindex="0">
        <a class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
           href="#" onclick="window.history.back();return false;"
           target="_self"
           role="button"
           data-upgraded=",MaterialButton,MaterialRipple">
            <i class="material-icons" role="presentation">arrow_back</i>
            <span class="mdl-button__ripple-container">
                <span class="mdl-ripple"></span>
            </span>
        </a>
    </div>
    -->


    <!-- Left aligned menu below button -->
    
    
    <button id="post-toc-trigger-btn"
        class="mdl-button mdl-js-button mdl-button--icon">
        <i class="material-icons">format_list_numbered</i>
    </button>

    <ul class="post-toc-wrap mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="post-toc-trigger-btn" style="max-height:80vh; overflow-y:scroll;">
        <ol class="post-toc"><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#JVM学习01-JVM内存模型"><span class="post-toc-number">1.</span> <span class="post-toc-text">JVM学习01-JVM内存模型</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#1-JVM-简介"><span class="post-toc-number">2.</span> <span class="post-toc-text">1. JVM 简介</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#2-JVM-启动流程"><span class="post-toc-number">3.</span> <span class="post-toc-text">2. JVM 启动流程</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#3-JVM-内存模型"><span class="post-toc-number">4.</span> <span class="post-toc-text">3. JVM 内存模型</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#3-1-程序计数器"><span class="post-toc-number">4.1.</span> <span class="post-toc-text">3.1 程序计数器</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#3-2-java虚拟机栈"><span class="post-toc-number">4.2.</span> <span class="post-toc-text">3.2 java虚拟机栈</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#3-3-本地方法栈"><span class="post-toc-number">4.3.</span> <span class="post-toc-text">3.3 本地方法栈</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#3-4-java堆"><span class="post-toc-number">4.4.</span> <span class="post-toc-text">3.4 java堆</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#3-5-方法区"><span class="post-toc-number">4.5.</span> <span class="post-toc-text">3.5 方法区</span></a></li></ol></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#4-线程工作的内存模型"><span class="post-toc-number">5.</span> <span class="post-toc-text">4. 线程工作的内存模型</span></a></li></ol>
    </ul>
    




<!-- Layouts -->

    <!-- Post Module -->
    <div class="material-post_container">

        <div class="material-post mdl-grid">
            <div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">

                <!-- Post Header(Thumbnail & Title) -->
                
    <!-- Paradox Post Header -->
    
        
            <!-- Random Thumbnail -->
            <div class="post_thumbnail-random mdl-card__media mdl-color-text--grey-50">
            <script type="text/ls-javascript" id="post-thumbnail-script">
    var randomNum = Math.floor(Math.random() * 19 + 1);

    $('.post_thumbnail-random').attr('data-original', '/img/random/material-' + randomNum + '.png');
    $('.post_thumbnail-random').addClass('lazy');
</script>

        
    
            <p class="article-headline-p">
                JVM学习01-JVM内存模型
            </p>
        </div>





                
                    <!-- Paradox Post Info -->
                    <div class="mdl-color-text--grey-700 mdl-card__supporting-text meta">

    <!-- Author Avatar -->
    <div id="author-avatar">
        <img src="/img/avatar.png" width="44px" height="44px" alt="Author Avatar"/>
    </div>
    <!-- Author Name & Date -->
    <div>
        <strong>xinwii</strong>
        <span>3月 12, 2017</span>
    </div>

    <div class="section-spacer"></div>

    <!-- Favorite -->
    <!--
        <button id="article-functions-like-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon btn-like">
            <i class="material-icons" role="presentation">favorite</i>
            <span class="visuallyhidden">favorites</span>
        </button>
    -->

    <!-- Qrcode -->
    

    <!-- Tags (bookmark) -->
    
    <button id="article-functions-viewtags-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
        <i class="material-icons" role="presentation">bookmark</i>
        <span class="visuallyhidden">bookmark</span>
    </button>
    <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-functions-viewtags-button">
        <li class="mdl-menu__item">
        <a class="post_tag-link" href="/tags/java/">java</a>
    </ul>
    

    <!-- Share -->
    
        <button id="article-fuctions-share-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
    <i class="material-icons" role="presentation">share</i>
    <span class="visuallyhidden">share</span>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-fuctions-share-button">
    
    <!-- Leancloud Views -->
        <a class="post_share-link" href="#">
            <li class="mdl-menu__item">
                <span id="/2017/03/12/java/JVM学习01-JVM内存模型/" class="leancloud-views_num" data-flag-title="JVM学习01-JVM内存模型">
     &nbsp;浏览量
</span>

            </li>
        </a>
    

    

    <!-- Share Weibo -->
    
        <a class="post_share-link" href="http://service.weibo.com/share/share.php?appkey=&title=JVM学习01-JVM内存模型&url=http://www.xincc.top/2017/03/12/java/JVM学习01-JVM内存模型/index.html&pic=http://www.xincc.top/img/favicon.png&searchPic=false&style=simple" target="_blank">
            <li class="mdl-menu__item">
                分享到微博
            </li>
        </a>
    

    <!-- Share Twitter -->
    
        <a class="post_share-link" href="https://twitter.com/intent/tweet?text=JVM学习01-JVM内存模型&url=http://www.xincc.top/2017/03/12/java/JVM学习01-JVM内存模型/index.html&via=xinwii" target="_blank">
            <li class="mdl-menu__item">
                分享到 Twitter
            </li>
        </a>
    

    <!-- Share Facebook -->
    
        <a class="post_share-link" href="https://www.facebook.com/sharer/sharer.php?u=http://www.xincc.top/2017/03/12/java/JVM学习01-JVM内存模型/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Facebook
            </li>
        </a>
    

    <!-- Share Google+ -->
    
        <a class="post_share-link" href="https://plus.google.com/share?url=http://www.xincc.top/2017/03/12/java/JVM学习01-JVM内存模型/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Google+
            </li>
        </a>
    

    <!-- Share LinkedIn -->
    

    <!-- Share QQ -->
    

    <!-- Share Telegram -->
    
</ul>

    
</div>

                

                <!-- Post Content -->
                <div id="post-content" class="mdl-color-text--grey-700 mdl-card__supporting-text fade out">
    
        <p>[TOC]</p>
<h1 id="JVM学习01-JVM内存模型"><a href="#JVM学习01-JVM内存模型" class="headerlink" title="JVM学习01-JVM内存模型"></a>JVM学习01-JVM内存模型</h1><h1 id="1-JVM-简介"><a href="#1-JVM-简介" class="headerlink" title="1. JVM 简介"></a>1. JVM 简介</h1><p>JVM(Java Virtual Machine)是java虚拟机的缩写，JVM是一个虚构出来的计算机，并给出了一套JVM的规范。java虚拟机包括一套字节码指令、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。JVM屏蔽了与操作系统平台相关的信息，它只需要知道java文件最后生成的字节码文件，就能够将字节码生成具体与平台相关的机器指令，然后就可以在不同平台上不加修改的运行。这也是java跨平台的重要特点，一次编译，到处运行。</p>
<h1 id="2-JVM-启动流程"><a href="#2-JVM-启动流程" class="headerlink" title="2. JVM 启动流程"></a>2. JVM 启动流程</h1><p>当我们执行命令 “java Xxx” 之后，JVM就开始启动进行对java字节码的执行，启动流程如下。<br><img src="http://img.blog.csdn.net/20160102210205161" alt="这里写图片描述"></p>
<ul>
<li><strong>1. 装载环境配置</strong></li>
</ul>
<p>当运行java指令即java.exe后，就会获取到java的安装路径。然后通过路径去查找java.dll来确定jre的路径，最后找不到就通过java的版本来确定。确定好jre路径后，通过路径去寻找JVM.cfg文件，读取配置确定需要装载的JVM.dll。</p>
<ul>
<li><strong>2. 装载JVM.dll</strong></li>
</ul>
<p>获取到JVM.dll之后就开始对该文件的装载，而JVM.dll就是JVM的主要的实现。</p>
<ul>
<li><strong>3. 初始化JVM，获取JNIEnv实例</strong></li>
</ul>
<p>初始化JVM之后就可以通过JNI调用本地方法来获取JNIEnv的实例，而通过JNIEnv实例，我们可以调用如findClass等操作来获取需要执行的class。由于运行java实例有两种途径，一种是java -jar，还有一种是.class直接运行。通过jar运行的时候会去获取META-INF/MANIFEST.MF指定的Main-Class的主类名作为运行的主类，通过.class运行的话就直接获取到了class运行的主类。</p>
<ul>
<li><strong>4. 运行main方法</strong></li>
</ul>
<p>通过JNIEnv实例获取到运行的主类，最后找到main方法后进行执行。</p>
<p>详细参考：<a href="http://www.jfox.info/start-process-virtual-machine-jvm-process-one-jvm" target="_blank" rel="noopener">《JVM虚拟机的启动流程原理》</a></p>
<h1 id="3-JVM-内存模型"><a href="#3-JVM-内存模型" class="headerlink" title="3. JVM 内存模型"></a>3. JVM 内存模型</h1><p>下面是JVM的内存模型图，稍微对网上的图进行了一下整合修改：<br><img src="http://img.blog.csdn.net/20160102210334712" alt="这里写图片描述"><br>下面对内存模型做下基本的介绍：</p>
<h2 id="3-1-程序计数器"><a href="#3-1-程序计数器" class="headerlink" title="3.1 程序计数器"></a>3.1 程序计数器</h2><p><code>程序计数器（Program Counter Register）</code>是一块较小的内存空间，由于多个线程之间需要进程CPU的资源，所以当处于运行状态的线程需要知道下一条运行的字节码指令的时候，就需要通过程序计数器来选取，所以每个线程都需要一个独立的程序计数器，即程序计数器时线程私有的。</p>
<h2 id="3-2-java虚拟机栈"><a href="#3-2-java虚拟机栈" class="headerlink" title="3.2 java虚拟机栈"></a>3.2 java虚拟机栈</h2><p>java栈中保存着java方法执行的内存模型，由于保存的是每个线程方法的运行时参数，所以栈是线程私有的。栈是由一系列的帧组成的（java栈有时也叫<code>帧栈</code>），每个方法执行的时候都会创建一个帧压入栈中，用来存储局部变量、操作数栈、动态链接、方法出口等信息。</p>
<ul>
<li><strong>1. 存储局部变量</strong></li>
</ul>
<p>局部变量包括方法的参数和方法内的变量。局部变量区被组织为以一个字长为单位、从0开始计数的数组，类型为short、byte和char的值在存入数组前要被转换成int值，而long和double在数组中占据连续的两项。<br>这个方法又分为<code>静态方法</code>和<code>实例方法</code>：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public static int runClassMethod(int i,long l,float f,double d,Object o,byte b) &#123;     </span><br><span class="line">    return 0;     </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>runClassMethod ：<br><img src="http://img.blog.csdn.net/20160102210420891" alt="这里写图片描述"></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public int runInstanceMethod(char c,double d,short s,boolean b) &#123;     </span><br><span class="line">     return 0;     </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>runInstanceMethod ：<br><img src="http://img.blog.csdn.net/20160102210436718" alt="这里写图片描述"></p>
<p>这里需要注意两点：</p>
<ul>
<li>第一从图中可以明显看出，实例方法的在存储局部变量的时候明显比静态方法<code>多了一个对自身引用</code>的存储，这个我们在调用方法的时候能够理解，因为静态方法是不用使用this的。</li>
<li><p>第二，由于每调用一个方法就会为该线程创建一个帧，那么当我们调用方法的深度很深的时候（如递归），那么可能就会导致栈溢出（stackOverflowError）。栈的大小决定方法调用的深度（栈深度或者帧的数量），如果栈的大小是固定的，栈深度如果超过了栈最大深度，那么就会导致栈溢出（stackOverflowError）；当然如果栈的大小是可以伸缩的，在超过内存空间的时候，则抛出OutofMemoryError。我们可以通过JVM参数 <code>-Xss</code>参数来设置分配栈的大小。</p>
</li>
<li><p><strong>2. 操作数栈</strong></p>
</li>
</ul>
<p>操作数栈和局部变量区的结构基本一样，但不是通过索引进行访问的，而是通过压栈和出栈的方式访问。操作数栈可以理解为一个计算产生值的一个临时存储区域。<br>如当运行该方法的时候：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> a,<span class="keyword">int</span> b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> c=<span class="number">0</span>;</span><br><span class="line">    c=a+b;</span><br><span class="line">    <span class="keyword">return</span> c;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 反编译后的指令</span></span><br><span class="line"><span class="comment">/* 第一行代码L2 */</span></span><br><span class="line"><span class="number">0</span> iconst_0;               <span class="comment">/* 将0压入栈中 */</span></span><br><span class="line"><span class="number">1</span> istore_2;               <span class="comment">/* 弹出, 存储在局部变量2中即c中 */</span></span><br><span class="line"><span class="comment">/* 第二行代码L3 */</span></span><br><span class="line"><span class="number">2</span> iload_0;                <span class="comment">/* 局部变量0即a压栈 */</span></span><br><span class="line"><span class="number">3</span> iload_1;                <span class="comment">/* 局部变量1即b压栈 */</span></span><br><span class="line"><span class="number">4</span> iadd;                   <span class="comment">/* 弹出两个变量求和, 并将结果压入栈中*/</span></span><br><span class="line"><span class="number">5</span> istore_2;               <span class="comment">/* 弹出结果, 存储到局部变量2即c中 */</span></span><br><span class="line"><span class="comment">/* 第三行代码L4 */</span></span><br><span class="line"><span class="number">6</span> iload_2;                <span class="comment">/* 将局部变量2即c压入栈中 */</span></span><br><span class="line"><span class="number">7</span> ireturn;                <span class="comment">/* 弹出返回 */</span></span><br></pre></td></tr></table></figure>
<p>运行add(100,98)的时候：<br><img src="http://img.blog.csdn.net/20160102210551018" alt="这里写图片描述"><br>从图中可以看出，操作数栈是一个数据的临时存储区域，通过压栈和出栈进行操作。</p>
<ul>
<li><strong>3. 其他</strong></li>
</ul>
<p>除了保存局部变量区和操作数栈外，Java栈帧还需要一些数据来支持常量池解析、正常方法返回以及异常派发机制。</p>
<ul>
<li><ol>
<li>当JVM执行到需要常量池数据的指令时，它都会通过帧数据区中指向常量池的指针来访问它。</li>
</ol>
</li>
<li><ol start="2">
<li>除了处理常量池解析外，帧里的数据还要处理Java方法的正常结束和异常终止。<ul>
<li>2.1 如果是通过return正常结束，则当前栈帧从Java栈中弹出，恢复到发起调用的方法（上一层方法）的栈。如果方法有返回值，JVM会把返回值压入到发起调用方法（上一层方法）的操作数栈。</li>
<li>2.2 为了处理Java方法中的异常情况，帧数据区还必须保存一个对此方法异常引用表的引用。当异常抛出时，JVM运行catch块中的代码。如果没有catch，当前方法立即终止，然后JVM用帧区域数据的信息恢复发起调用的方法（上一层方法）的帧，然后再在当前的方法中重新抛出同样的异常，直到能够被当前方法或者上一层方法处理为止，不能处理则直接抛出异常。</li>
</ul>
</li>
</ol>
</li>
</ul>
<h2 id="3-3-本地方法栈"><a href="#3-3-本地方法栈" class="headerlink" title="3.3 本地方法栈"></a>3.3 本地方法栈</h2><p>直接摘抄了：<code>本地方法栈（Native Method Stacks）</code>与虚拟机栈所发挥的作用是非常相似的，其区别不过是虚拟机栈为虚拟机执行Java 方法（也就是字节码）服务，而本地方法栈则是为虚拟机使用到的Native 方法服务。虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定，因此具体的虚拟机可以自由实现它。甚至有的虚拟机（譬如Sun HotSpot 虚拟机）直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样，本地方法栈区域也会抛出StackOverflowError 和OutOfMemoryError异常。</p>
<h2 id="3-4-java堆"><a href="#3-4-java堆" class="headerlink" title="3.4 java堆"></a>3.4 java堆</h2><p>java堆（heap）是JVM管理内存中最大的一个部分，是线程共享的。存放着对象的实例和数组。几乎所有的对象的实例都在堆上分配内存，<code>这里的几乎</code>是因为还有可能存在栈上分配内存的情况。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">栈上分配：直接将数据对象分配在栈中.</span><br><span class="line">1. 一般小对象（几十个Byte）,在没有逃逸的情况下, 可以直接分配在栈上</span><br><span class="line">2. 直接分配在栈上, 可以直接回收, 减轻GC的压力</span><br><span class="line">3. 大对象或逃逸对象只能分配在堆上</span><br><span class="line">逃逸：指不是线程私有的对象, 也被其他线程所使用到的对象.</span><br></pre></td></tr></table></figure>
<p>java堆是垃圾收集器管理的主要区域，有时候也被称为”GC堆(Garbage Collected Heap)”。<br>java堆又分为<strong>新生代、老年代以及持久代</strong>，这里先不说持久态。<br>新生代用于存放刚创建或者年经的对象；老年代存放年龄比较老的对象，譬如新生代中的对象一直没有被回收，生存时间足够长，或者对象太大新生代无法创建都会被存放到老年代中；<br>java的新生代又可以进一步划分为<strong>eden，From Survivor（s0），To Survivor（s1）。</strong>之所以这么划分是跟GC算法息息相关的，这里只需要知道新生代被划分为这几个空间就好了。</p>
<p><img src="http://img.blog.csdn.net/20160102210716868" alt="这里写图片描述"></p>
<h2 id="3-5-方法区"><a href="#3-5-方法区" class="headerlink" title="3.5 方法区"></a>3.5 方法区</h2><p>方法区（在Hotspot中常被称为永久代）中保存中虚拟机加载的类的元数据信息：如类信息、常量池、静态字段、方法等数据。<br>这里有个概念容易让人混淆，就是方法区在物理上存储在堆中的，但是逻辑上是方法区和堆独立的。<br>所以，有的时候堆还可以在划分出一个区域叫做Perm区域（持久代），默认为64M，持久代一般就是指方法区，JVM将方法区加载进内存之后，这些内存通常是不会被回收的。由于持久代是Hotspot中的一个概念，所以持久代在堆中还是方法区中并没有定论，最新的HotSpot也计划将其移除。<br>这里注意一点：jdk6将String等常量信息放置在方法区中，jdk7已经移动到了堆中。<br>但是如果hotspot虚拟机确定一个类的定义信息不会被使用，也会将其回收。回收的基本条件至少有：所有该类的实例被回收，而且装载该类的ClassLoader被回收。</p>
<h1 id="4-线程工作的内存模型"><a href="#4-线程工作的内存模型" class="headerlink" title="4. 线程工作的内存模型"></a>4. 线程工作的内存模型</h1><p>每一个线程都一个和主存相独立的工作内存，工作内存中存放着主存中变量值的一个拷贝（副本）。</p>
<ul>
<li><p>当数据从主内存复制到工作存储时，必须出现两个动作：</p>
<ul>
<li>第一，由主内存执行的读（read）操作；</li>
<li>第二，由工作内存执行的相应的load操作；</li>
</ul>
</li>
<li><p>当数据从工作内存拷贝到主内存时，也出现两个操作：</p>
<ul>
<li>第一，由工作内存执行的存储（store）操作；</li>
<li>第二，由主内存执行的相应的写（write）操作，每一个操作都是原子的，即执行期间不会被中断。</li>
</ul>
</li>
</ul>
<p><img src="http://img.blog.csdn.net/20160102210752488" alt="这里写图片描述"></p>
<p>对于普通变量，一个线程中更新的值，不能马上反应在其他变量中。如果需要在其他线程中立即可见，需要使用 volatile 关键字。<br>但是volatile仅仅只能保证每个线程读取的变量值是主存中最新的，但是不能保证变量的操作是原子性的。要保证线程的安全，还得使用java的同步机制。关于volatile的详细可参考其他博文。</p>

        
    

    
</div>


                

                <!-- Post Comments -->
                
                    
    <div id="comment" style='padding:10px;' class="vcomment"></div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="//unpkg.com/valine/dist/Valine.min.js"></script>
<script>
    var GUEST_INFO = ['nick','mail','link'];
    var guest_info = 'nick,mail,link'.split(',').filter(function(item){
        return GUEST_INFO.indexOf(item) > -1
    });
    var notify = 'false' == true;
    var verify = 'false' == true;
    new Valine({
        el: '.vcomment',
        notify: notify,
        verify: verify,
        appId: "vEOpfYrMUTPxez4tOTNQJv9A-gzGzoHsz",
        appKey: "qlbEzWd9EJ3vHa07eHpWPIVU",
        placeholder: "Just go go",
        pageSize:'10',
        avatar:'identicon',
        lang:'zh-cn'
    });
</script>

                
            </div>

            <!-- Post Prev & Next Nav -->
            <nav class="material-nav mdl-color-text--grey-50 mdl-cell mdl-cell--12-col">
    <!-- Prev Nav -->
    
        <a href="/2017/03/15/java/JVM学习02-GC算法与种类/" id="post_nav-newer" class="prev-content">
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_back</i>
            </button>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            新篇
        </a>
    

    <!-- Section Spacer -->
    <div class="section-spacer"></div>

    <!-- Next Nav -->
    
        <a href="/2017/03/10/java/[转]java的三种代理模式/" id="post_nav-older" class="next-content">
            旧篇
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_forward</i>
            </button>
        </a>
    
</nav>

        </div>
    </div>



                    
                        <!-- Overlay For Active Sidebar -->
<div class="sidebar-overlay"></div>

<!-- Material sidebar -->
<aside id="sidebar" class="sidebar sidebar-colored sidebar-fixed-left" role="navigation">
    <div id="sidebar-main">
        <!-- Sidebar Header -->
        <div class="sidebar-header header-cover" style="background-image: url(/img/sidebar_header.png);">
    <!-- Top bar -->
    <div class="top-bar"></div>

    <!-- Sidebar toggle button -->
    <button type="button" class="sidebar-toggle mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon" style="display: initial;" data-upgraded=",MaterialButton,MaterialRipple">
        <i class="material-icons">clear_all</i>
        <span class="mdl-button__ripple-container">
            <span class="mdl-ripple">
            </span>
        </span>
    </button>

    <!-- Sidebar Avatar -->
    <div class="sidebar-image">
        <img src="/img/avatar.png" alt="xinwii's avatar">
    </div>

    <!-- Sidebar Email -->
    <a data-toggle="dropdown" class="sidebar-brand" href="#settings-dropdown">
        mestic@foxmail.com
        <b class="caret"></b>
    </a>
</div>


        <!-- Sidebar Navigation  -->
        <ul class="nav sidebar-nav">
    <!-- User dropdown  -->
    <li class="dropdown">
        <ul id="settings-dropdown" class="dropdown-menu">
            
                <li>
                    <a href="mailto:mestic@foxmail.com" target="_blank" title="Email Me">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        Email Me
                    </a>
                </li>
            
        </ul>
    </li>

    <!-- Homepage -->
    
        <li id="sidebar-first-li">
            <a href="/">
                
                    <i class="material-icons sidebar-material-icons">home</i>
                
                主页
            </a>
        </li>
        
    

    <!-- Archives  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">inbox</i>
                
                    归档
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
            <li>
                <a class="sidebar_archives-link" href="/archives/2018/06/">六月 2018<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/05/">五月 2018<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/04/">四月 2018<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/01/">一月 2018<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/08/">八月 2017<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/06/">六月 2017<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/04/">四月 2017<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/03/">三月 2017<span class="sidebar_archives-count">8</span></a></li><li><a class="sidebar_archives-link" href="/archives/2017/01/">一月 2017<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/12/">十二月 2016<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2016/01/">一月 2016<span class="sidebar_archives-count">6</span></a>
            </ul>
        </li>
        
    

    <!-- Categories  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">chrome_reader_mode</i>
                
                分类
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
                <li>
                <a class="sidebar_archives-link" href="/categories/android/">android<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/categories/java/">java<span class="sidebar_archives-count">18</span></a></li><li><a class="sidebar_archives-link" href="/categories/mysql/">mysql<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/categories/weex/">weex<span class="sidebar_archives-count">1</span></a>
            </ul>
        </li>
        
            <li class="divider"></li>
        
    

    <!-- Pages  -->
    
        <li>
            <a href="/about" title="关于我">
                
                    <i class="material-icons sidebar-material-icons">person</i>
                
                关于我
            </a>
        </li>
        
    

    <!-- Article Number  -->
    
</ul>


        <!-- Sidebar Footer -->
        <!--
I'm glad you use this theme, the development is no so easy, I hope you can keep the copyright, I will thank you so much.
If you still want to delete the copyrights, could you still retain the first one? Which namely "Theme Material"
It will not impact the appearance and can give developers a lot of support :)

很高兴您使用并喜欢该主题，开发不易 十分谢谢与希望您可以保留一下版权声明。
如果您仍然想删除的话 能否只保留第一项呢？即 "Theme Material"
它不会影响美观并可以给开发者很大的支持和动力。 :)
-->

<!-- Sidebar Divider -->

    <div class="sidebar-divider"></div>


<!-- Theme Material -->

    <a href="https://github.com/viosey/hexo-theme-material"  class="sidebar-footer-text-a" target="_blank">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
            主题 - Material
            <span class="sidebar-badge badge-circle">i</span>
        </div>
    </a>


<!-- Help & Support -->
<!--

-->

<!-- Feedback -->
<!--

-->

<!-- About Theme -->
<!--

    <a href="https://blog.viosey.com/index.php/Material.html" target="_blank" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
             sidebar.about_theme
            <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
    </a>

-->

    </div>

    <!-- Sidebar Image -->
    

</aside>

                    

                    
                        <!-- Footer Top Button -->
                        <div id="back-to-top" class="toTop-wrap">
    <a href="#top" class="toTop">
        <i class="material-icons footer_top-i">expand_less</i>
    </a>
</div>

                    

                    <!--Footer-->
<footer class="mdl-mini-footer" id="bottom">
    
        <!-- Paradox Footer Left Section -->
        <div class="mdl-mini-footer--left-section sns-list">
    <!-- Twitter -->
    

    <!-- Facebook -->
    

    <!-- Google + -->
    

    <!-- Weibo -->
    

    <!-- Instagram -->
    

    <!-- Tumblr -->
    

    <!-- Github -->
    
        <a href="https://github.com/xinwii" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-github">
                <span class="visuallyhidden">Github</span>
            </button><!--
     --></a>
    

    <!-- LinkedIn -->
    

    <!-- Zhihu -->
    

    <!-- Bilibili -->
    

    <!-- Telegram -->
    

    <!-- V2EX -->
    

    <!-- Segmentfault -->
    

    <p>Hosted by <a href="https://pages.coding.me" style="font-weight: bold">Coding Pages</a></p>
</div>


        <!--Copyright-->
        <div id="copyright">
            Copyright&nbsp;©&nbsp;<span year></span>&nbsp;android开发者
            
        </div>

        <!-- Paradox Footer Right Section -->

        <!--
        I am glad you use this theme, the development is no so easy, I hope you can keep the copyright.
        It will not impact the appearance and can give developers a lot of support :)

        很高兴您使用该主题，开发不易，希望您可以保留一下版权声明。
        它不会影响美观并可以给开发者很大的支持。 :)
        -->

        <div class="mdl-mini-footer--right-section">
            <div>
                <div class="footer-develop-div">Powered by Hexo</div>
                <div class="footer-develop-div">Theme - Material</div>
            </div>
        </div>
    
</footer>


                    <!-- Import JS File -->

    <script>lsloader.load("lazyload_js","/js/lazyload.min.js?1BcfzuNXqV+ntF6gq+5X3Q==", true)</script>



    <script>lsloader.load("js_js","/js/js.min.js?V/53wGualMuiPM3xoetD5Q==", true)</script>



    <script>lsloader.load("np_js","/js/nprogress.js?pl3Qhb9lvqR1FlyLUna1Yw==", true)</script>


<script type="text/ls-javascript" id="NProgress-script">
    NProgress.configure({
        showSpinner: true
    });
    NProgress.start();
    $('#nprogress .bar').css({
        'background': '#29d'
    });
    $('#nprogress .peg').css({
        'box-shadow': '0 0 10px #29d, 0 0 15px #29d'
    });
    $('#nprogress .spinner-icon').css({
        'border-top-color': '#29d',
        'border-left-color': '#29d'
    });
    setTimeout(function() {
        NProgress.done();
        $('.fade').removeClass('out');
    }, 800);
</script>





    <!-- Leancloud -->
    <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
    <script>
        AV.initialize('vEOpfYrMUTPxez4tOTNQJv9A-gzGzoHsz', 'qlbEzWd9EJ3vHa07eHpWPIVU');
    </script>
    <script type="text/ls-javascript" id="leancloud-views-script">
    function showTime(Counter) {
        var query = new AV.Query(Counter);
        $('.leancloud-views_num').each(function() {
            var url = $(this).attr('id').trim();
            query.equalTo('url', url);
            query.find({
                success: function(results) {
                    if (results.length === 0) {
                        var content = '0 ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                        return;
                    }
                    for (var i = 0; i < results.length; i++) {
                        var object = results[i];
                        var content = object.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    }
                },
                error: function(object, error) {
                    console.log('Error: ' + error.code + ' ' + error.message);
                }
            });
        });
    }

    function addCount(Counter) {
      var Counter = AV.Object.extend('Counter');
      url = $('.leancloud-views_num').attr('id').trim();
      title = $('.leancloud-views_num').attr('data-flag-title').trim();
      var query = new AV.Query(Counter);
      query.equalTo('url', url);
      query.find({
          success: function(results) {
            if (results.length > 0) {
                var counter = results[0];
                counter.fetchWhenSave(true);
                counter.increment('time');
                counter.save(null, {
                    success: function(counter) {
                        var content =  counter.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    },
                    error: function(counter, error) {
                        console.log('Failed to save Visitor num, with error message: ' + error.message);
                    }
                });
            } else {
              var newcounter = new Counter();
              newcounter.set('title', title);
              newcounter.set('url', url);
              newcounter.set('time', 1);
              newcounter.save(null, {
                  success: function(newcounter) {
                      console.log('newcounter.get(\'time\')='+newcounter.get('time'));
                      var content = newcounter.get('time') + ' ' + $(document.getElementById(url)).text();
                      $(document.getElementById(url)).text(content);
                  },
                  error: function(newcounter, error) {
                      console.log('Failed to create');
                  }
              });
            }
        },
        error: function(error) {
            console.log('Error:' + error.code + ' ' + error.message);
        }
      });
    }
    $(function() {
        var Counter = AV.Object.extend('Counter');
        if ($('.leancloud-views_num').length === 1) {
            addCount(Counter);
        } else if ($('.post-title-link').length > 1) {
            showTime(Counter);
        }
    });
</script>






   





<!-- UC Browser Compatible -->
<script>
	var agent = navigator.userAgent.toLowerCase();
	if(agent.indexOf('ucbrowser')>0) {
		document.write('<link rel="stylesheet" href="/css/uc.css">');
	   alert('由于 UC 浏览器使用极旧的内核，而本网站使用了一些新的特性。\n为了您能更好的浏览，推荐使用 Chrome 或 Firefox 浏览器。');
	}
</script>

<!-- Import prettify js  -->



<!-- Window Load -->
<!-- add class for prettify -->
<script type="text/ls-javascript" id="window-load">
    $(window).on('load', function() {
        // Post_Toc parent position fixed
        $('.post-toc-wrap').parent('.mdl-menu__container').css('position', 'fixed');
    });

    
    
</script>

<!-- MathJax Load-->


<!-- Bing Background -->


<script type="text/ls-javascript" id="lazy-load">
    // Offer LazyLoad
    queue.offer(function(){
        $('.lazy').lazyload({
            effect : 'show'
        });
    });

    // Start Queue
    $(document).ready(function(){
        setInterval(function(){
            queue.execNext();
        },200);
    });
</script>

<!-- Custom Footer -->



<script>
    var copyrightNow = new Date().getFullYear();
    var textContent = document.querySelector('span[year]')

    copyrightSince = 2015;
    if (copyrightSince === copyrightNow||copyrightSince === 0000) {
        textContent.textContent = copyrightNow
    } else {
        textContent.textContent = copyrightSince + ' - ' + copyrightNow
    }

    (function(){
        var scriptList = document.querySelectorAll('script[type="text/ls-javascript"]')

        for (var i = 0; i < scriptList.length; ++i) {
            var item = scriptList[i];
            lsloader.runInlineScript(item.id,item.id);
        }
    })()
console.log('\n %c © Material Theme | Version: 1.5.2 | https://github.com/viosey/hexo-theme-material %c \n', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-left-radius:5px;border-bottom-left-radius:5px;', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-right-radius:5px;border-bottom-right-radius:5px;');
</script>

                </main>
            </div>
        <script src="/live2dw/lib/L2Dwidget.min.js?0c58a1486de42ac6cc1c59c7d98ae887"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","model":{"scale":1,"hHeadPos":0.5,"vHeadPos":0.618,"jsonPath":"/live2dw/assets/z16.model.json"},"display":{"superSample":2,"width":150,"height":300,"position":"right","hOffset":0,"vOffset":-20},"mobile":{"show":true,"scale":0.1},"react":{"opacityDefault":0.7,"opacityOnHover":0.2}});</script></body>
    
</html>
